package bit.client.model;

import java.io.IOException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jsoup.Jsoup;
import org.jsoup.Connection.Method;
import org.jsoup.Connection.Response;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class BitBasic {
    private String username;
    private String passwd;
    private String initUrl = "http://10.5.2.80";
    String userName;
    URL baseUrl;
    URL mainPageUrl;
    URL scoreURL;
    URL tableURL;
    URL examURL;

    public void login() throws PassWdError {
        try {
            Response response = Jsoup.connect(this.initUrl).execute();
            this.baseUrl = response.url();
            Document doc = response.parse();
            String viewstate = doc.select("input[name=__VIEWSTATE]").attr("value");
            String TargetUrl = (new URL(this.baseUrl, "default2.aspx")).toString();
            Map params = new HashMap();
            params.put("__VIEWSTATE", viewstate);
            params.put("TextBox1", this.username);
            params.put("TextBox2", this.passwd);
            params.put("RadioButtonList1", "%D1%A7%C9%FA");
            params.put("Button1", "+%B5%C7+%C2%BC+");
            response = Jsoup.connect(TargetUrl).method(Method.POST).data(params).execute();
            if (response.url().toString().equals(TargetUrl.toString())) {
                throw new PassWdError();
            }

            this.mainPageUrl = response.url();
            this.getEntrace(response);
            this.getName(response);
        } catch (IOException e) {
            System.out.println(e);
        }
    }

    public URL urlparse(URL rawUrl) {
        try {
            String query = rawUrl.getQuery();
            String[] key_val = query.split("&");
            List<String> newkey_val = new ArrayList();
            for (String kv : key_val) {
                String[] k_v = kv.split("=");
                k_v[1] = URLEncoder.encode(k_v[1], "gb2312");
                String newkv = String.join("=", k_v);
                newkey_val.add(newkv);
            }
            String parsedQuery = String.join("&", newkey_val);
            String newURL = (new URL("http", rawUrl.getHost(), rawUrl.getFile().split("\\?")[0])).toString();
            newURL = newURL + "?" + parsedQuery;
            return new URL(newURL);
        } catch (Exception e) {
            System.out.println(e);
            return null;
        }
    }

    private void getEntrace(Response response) {
        try {
            Elements alist = response.parse().select("a");
            for (Element a : alist) {
                if (a.text().equals("成绩")) {
                    this.scoreURL = this.urlparse(new URL(this.baseUrl, a.attr("href")));
                } else if (a.text().equals("课表")) {
                    this.tableURL = this.urlparse(new URL(this.baseUrl, a.attr("href")));
                } else if (a.text().equals("考试")) {
                    this.examURL = this.urlparse(new URL(this.baseUrl, a.attr("href")));
                }
            }
        } catch (Exception e) {
            System.out.println(e);
        }

    }

    private void getName(Response response) {
        try {
            Element target = response.parse().select("#xhxm").first();
            this.userName = target.text().split(" ")[1];
        } catch (Exception e) {
            System.out.println(e);
        }

    }

    public Response get(String url) throws IOException {
        boolean flag = true;
        Response response;
        do {
            response = Jsoup.connect(url).method(Method.GET).referrer(mainPageUrl.toString()).execute();
            if (response.url().getFile().equals("default2.aspx")) {
                try {
                    login();
                } catch (PassWdError e) {
                }
            } else flag = false;
        } while (flag);
        return response;
    }

    public Response get(URL url) throws IOException {
        boolean flag = true;
        Response response;
        do {
            response = Jsoup.connect(url.toString()).method(Method.GET).referrer(mainPageUrl.toString()).execute();
            if (response.url().getFile().equals("default2.aspx")) {
                try {
                    login();
                } catch (PassWdError e) {
                }
            } else flag = false;
        } while (flag);
        return response;
    }

    public Response post(String url, Map<String, String> param) throws IOException {
        boolean flag = true;
        Response response;
        do {
            response = Jsoup.connect(url).method(Method.POST).data(param).referrer(mainPageUrl.toString()).execute();
            if (response.url().getFile().equals("default2.aspx")) {
                try {
                    login();
                } catch (PassWdError e) {
                }
            } else flag = false;
        } while (flag);
        return response;
    }

    public Response post(URL url, Map<String, String> param) throws IOException {
        boolean flag = true;
        Response response;
        do {
            response = Jsoup.connect(url.toString()).method(Method.POST).data(param).referrer(mainPageUrl.toString()).execute();
            if (response.url().getFile().equals("default2.aspx")) {
                try {
                    login();
                } catch (PassWdError e) {
                }
            } else flag = false;
        } while (flag);
        return response;
    }

    BitBasic(String user, String pass) throws PassWdError {
        this.username = user;
        this.passwd = pass;
        this.login();
    }
}

class PassWdError extends Exception {
}
